# coding:utf-8
# 日志模块
import logging
import os
import time
import subprocess
import threading

"""constant and function about log"""

DEBUG = logging.DEBUG
INFO = logging.INFO
WARNING = logging.WARNING
ERROR = logging.ERROR
CRITICAL = logging.CRITICAL


class NetworkFormatter(logging.Formatter):
    def format(self, record):
        # 截取logger name到指定长度
        record.name = record.name[:7]
        return super().format(record)


def get_logger(host, level):
    """
    return a logger with FileHandler
    :param str host: host name
    :param int level: log level
    """
    # 获取当前进程ID
    pid = os.getpid()
    # 获取当前线程ID
    tid = threading.get_ident()
    # 获取当前时间
    now = time.strftime("%H%M%S", time.localtime())
    # 前缀+进程ID+线程ID组成唯一日志器名称
    logger_name = "network" + "_" + str(pid) + "_" + str(tid)
    # 主机名+当前时间组成日志文件名称
    log_file_name = host + "_" + now + ".log"
    # make log file
    log_file = _make_log_file(log_file_name)
    # set logger
    logger = logging.getLogger(logger_name)
    logger.setLevel(level)
    # set handler
    handler = logging.FileHandler(filename=log_file, encoding="utf-8")
    handler.setLevel(level)
    fmt = "%(levelname)-.3s [%(asctime)s.%(msecs)03d]  %(name)s.%(module)-15s.%(funcName)-23s : %(message)s"
    formatter = NetworkFormatter(fmt=fmt, datefmt="%Y%m%d-%H:%M:%S")
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    return logger


def _make_log_file(name):
    """
    create log file and return absolute path,also it will delete log file from a week ago
    :param str name: log file name, the host IP address or name is recommended
    """
    # create log base path
    base_path = "/tmp/log/network"
    if not os.path.exists(base_path):
        os.makedirs(base_path, exist_ok=True)
        time.sleep(0.5)
        command = ["chmod", "-R", "777", base_path]
        subprocess.run(command, check=True)
    # create log path
    log_path = time.strftime("%Y%m%d")
    fall_path = os.path.join(base_path, log_path)
    if not os.path.exists(fall_path):
        os.makedirs(fall_path, exist_ok=True)
        time.sleep(0.5)
        command = ["chmod", "-R", "777", fall_path]
        subprocess.run(command, check=True)
    # delete log file that out of date
    command = ["find", base_path, "-mindepth", "1", "-maxdepth", "1", "-type", "d", "-mtime", "+7", "-exec", "rm", "-r", "{}", ";"]
    try:
        with open(os.devnull, 'w') as devnull:
            subprocess.run(command, stdout=devnull, stderr=devnull, check=True)
    except FileNotFoundError:   # file may be deleted by other process
        pass
    # make log file
    log_file = os.path.join(fall_path, name)
    command = ["touch", log_file]
    subprocess.run(command, check=True)
    # return log file
    return log_file



if __name__ == '__main__':
    net_logger = get_logger("1.1.1.1", logging.DEBUG)
    net_logger.warning("test warning message")
    net_logger.error("also this is a test log message of level error")
